home *** CD-ROM | disk | FTP | other *** search
/ FishMarket 1.0 / FishMarket v1.0.iso / fishies / 051-075 / disk_053 / compiler / outcode.c < prev    next >
C/C++ Source or Header  |  1992-05-06  |  11KB  |  407 lines

  1. #include        <stdio.h>
  2. #include        "c.h"
  3. #include        "expr.h"
  4. #include        "gen.h"
  5. #include        "cglbdec.h"
  6.  
  7. /*
  8.  *    68000 C compiler
  9.  *
  10.  *    Copyright 1984, 1985, 1986 Matthew Brandt.
  11.  *    all commercial rights reserved.
  12.  *
  13.  *    This compiler is intended as an instructive tool for personal use. Any
  14.  *    use for profit without the written consent of the author is prohibited.
  15.  *
  16.  *    This compiler may be distributed freely for non-commercial use as long
  17.  *    as this notice stays intact. Please forward any enhancements or questions
  18.  *    to:
  19.  *
  20.  *        Matthew Brandt
  21.  *        Box 920337
  22.  *        Norcross, Ga 30092
  23.  */
  24.  
  25. /*      variable initialization         */
  26.  
  27. enum e_gt { nogen, bytegen, wordgen, longgen };
  28. enum e_sg { noseg, codeseg, dataseg };
  29.  
  30. enum e_gt gentype = nogen;
  31. enum e_sg curseg = noseg;
  32. int outcol = 0;
  33.  
  34. struct oplst {
  35.         char    *s;
  36.         int     ov;
  37.         }       opl[] =
  38.         {       {"mov",op_move}, {"mov",op_moveq}, {"add",op_add},
  39.                 {"add",op_addi}, {"add",op_addq}, {"sub",op_sub},
  40.                 {"sub",op_subi}, {"sub",op_subq}, {"and",op_and},
  41.                 {"or",op_or}, {"eor",op_eor}, {"muls",op_muls},
  42.                 {"divs",op_divs}, {"swap",op_swap}, {"beq",op_beq},
  43.                 {"bhi",op_bhi}, {"bhs",op_bhs}, {"blo",op_blo},
  44.                 {"bls",op_bls}, {"mulu",op_mulu}, {"divu",op_divu},
  45.                 {"bne",op_bne}, {"blt",op_blt}, {"ble",op_ble},
  46.                 {"bgt",op_bgt}, {"bge",op_bge}, {"neg",op_neg},
  47.                 {"not",op_not}, {"cmp",op_cmp}, {"ext",op_ext},
  48.                 {"jmp",op_jmp}, {"jsr",op_jsr}, {"rts",op_rts},
  49.                 {"lea",op_lea}, {"asr",op_asr}, {"asl",op_asl},
  50.                 {"clr",op_clr}, {"link",op_link}, {"unlk",op_unlk},
  51.                 {"bra",op_bra}, {"movm",op_movem}, {"pea",op_pea},
  52.                 {"cmp",op_cmpi}, {"tst",op_tst}, {"dc",op_dc},
  53.                 {0,0} };
  54.  
  55. putop(op)
  56. int     op;
  57. {       int     i;
  58.         i = 0;
  59.         while( opl[i].s )
  60.                 {
  61.                 if( opl[i].ov == op )
  62.                         {
  63.                         fprintf(output,"\t%s",opl[i].s);
  64.                         return;
  65.                         }
  66.                 ++i;
  67.                 }
  68.         printf("DIAG - illegal opcode.\n");
  69. }
  70.  
  71. putconst(offset)
  72. /*
  73.  *      put a constant to the output file.
  74.  */
  75. struct enode    *offset;
  76. {       switch( offset->nodetype )
  77.                 {
  78.                 case en_autocon:
  79.                 case en_icon:
  80.                         fprintf(output,"%d",offset->v.i);
  81.                         break;
  82.                 case en_labcon:
  83.                         fprintf(output,"L%%%d",offset->v.i);
  84.                         break;
  85.                 case en_nacon:
  86.                         fprintf(output,"%s",offset->v.p[0]);
  87.                         break;
  88.                 case en_add:
  89.                         putconst(offset->v.p[0]);
  90.                         fprintf(output,"+");
  91.                         putconst(offset->v.p[1]);
  92.                         break;
  93.                 case en_sub:
  94.                         putconst(offset->v.p[0]);
  95.                         fprintf(output,"-");
  96.                         putconst(offset->v.p[1]);
  97.                         break;
  98.                 case en_uminus:
  99.                         fprintf(output,"-");
  100.                         putconst(offset->v.p[0]);
  101.                         break;
  102.                 default:
  103.                         printf("DIAG - illegal constant node.\n");
  104.                         break;
  105.                 }
  106. }
  107.  
  108. putlen(l)
  109. /*
  110.  *      append the length field to an instruction.
  111.  */
  112. int     l;
  113. {       switch( l )
  114.                 {
  115.                 case 0:
  116.                         break;  /* no length field */
  117.                 case 1:
  118.                         fprintf(output,".b");
  119.                         break;
  120.                 case 2:
  121.                         fprintf(output,".w");
  122.                         break;
  123.                 case 4:
  124.                         fprintf(output,".l");
  125.                         break;
  126.                 default:
  127.                         printf("DIAG - illegal length field.\n");
  128.                         break;
  129.                 }
  130. }
  131.  
  132. putamode(ap)
  133. /*
  134.  *      output a general addressing mode.
  135.  */
  136. struct amode    *ap;
  137. {       switch( ap->mode )
  138.                 {
  139.                 case am_immed:
  140.                         fprintf(output,"&");
  141.                 case am_direct:
  142.                         putconst(ap->offset);
  143.                         break;
  144.                 case am_areg:
  145.                         fprintf(output,"%%a%d",ap->preg);
  146.                         break;
  147.                 case am_dreg:
  148.                         fprintf(output,"%%d%d",ap->preg);
  149.                         break;
  150.                 case am_ind:
  151.                         fprintf(output,"(%%a%d)",ap->preg);
  152.                         break;
  153.                 case am_ainc:
  154.                         fprintf(output,"(%%a%d)+",ap->preg);
  155.                         break;
  156.                 case am_adec:
  157.                         fprintf(output,"-(%%a%d)",ap->preg);
  158.                         break;
  159.                 case am_indx:
  160.                         putconst(ap->offset);
  161.                         fprintf(output,"(%%a%d)",ap->preg);
  162.                         break;
  163.                 case am_xpc:
  164.                         putconst(ap->offset);
  165.                         fprintf(output,"(%%d%d,%%pc)",ap->preg);
  166.                         break;
  167.                 case am_indx2:
  168.                         putconst(ap->offset);
  169.                         fprintf(output,"(%%a%d,%%d%d.l)",ap->preg,ap->sreg);
  170.                         break;
  171.                 case am_indx3:
  172.                         putconst(ap->offset);
  173.                         fprintf(output,"(%%a%d,%%a%d.l)",ap->preg,ap->sreg);
  174.                         break;
  175.                 case am_mask:
  176.                         put_mask(ap->offset);
  177.                         break;
  178.                 default:
  179.                         printf("DIAG - illegal address mode.\n");
  180.                         break;
  181.                 }
  182. }
  183.  
  184. put_code(op,len,aps,apd)
  185. /*
  186.  *      output a generic instruction.
  187.  */
  188. struct amode    *aps, *apd;
  189. enum e_op    op;
  190. int             len;
  191. {       if( op == op_dc )
  192.         {
  193.         switch( len )
  194.             {
  195.             case 1: fprintf(output,"\tbyte"); break;
  196.             case 2: fprintf(output,"\tshort"); break;
  197.             case 4: fprintf(output,"\tlong"); break;
  198.             }
  199.         }
  200.     else
  201.         {
  202.         putop(op);
  203.             putlen(len);
  204.         }
  205.         if( aps != 0 )
  206.                 {
  207.                 fprintf(output,"\t");
  208.         if( op == op_cmp || op == op_cmpi )
  209.             putamode( apd );
  210.         else
  211.             putamode(aps);
  212.                 if( apd != 0 )
  213.                         {
  214.                         fprintf(output,",");
  215.             if( op == op_cmp || op == op_cmpi )
  216.                 putamode( aps );
  217.             else
  218.                             putamode(apd);
  219.                         }
  220.                 }
  221.         fprintf(output,"\n");
  222. }
  223.  
  224. put_mask(mask)
  225. /*
  226.  *      generate a register mask for restore and save.
  227.  */
  228. int     mask;
  229. {       int     i;
  230.         fprintf(output,"&0x%04x",mask);
  231. }
  232.  
  233. putreg(r)
  234. /*
  235.  *      generate a register name from a tempref number.
  236.  */
  237. int     r;
  238. {       if( r < 8 )
  239.                 fprintf(output,"D%d",r);
  240.         else
  241.                 fprintf(output,"A%d",r - 8);
  242. }
  243.  
  244. gen_strlab(s)
  245. /*
  246.  *      generate a named label.
  247.  */
  248. char    *s;
  249. {       fprintf(output,"%s:\n",s);
  250. }
  251.  
  252. put_label(lab)
  253. /*
  254.  *      output a compiler generated label.
  255.  */
  256. int     lab;
  257. {       fprintf(output,"L%%%d:\n",lab);
  258. }
  259.  
  260. genbyte(val)
  261. int     val;
  262. {       if( gentype == bytegen && outcol < 60) {
  263.                 fprintf(output,",%d",val & 0x00ff);
  264.                 outcol += 4;
  265.                 }
  266.         else    {
  267.                 nl();
  268.                 fprintf(output,"\tbyte\t%d",val & 0x00ff);
  269.                 gentype = bytegen;
  270.                 outcol = 19;
  271.                 }
  272. }
  273.  
  274. genword(val)
  275. int     val;
  276. {       if( gentype == wordgen && outcol < 58) {
  277.                 fprintf(output,",%d",val & 0x0ffff);
  278.                 outcol += 6;
  279.                 }
  280.         else    {
  281.                 nl();
  282.                 fprintf(output,"\tshort\t%d",val & 0x0ffff);
  283.                 gentype = wordgen;
  284.                 outcol = 21;
  285.                 }
  286. }
  287.  
  288. genlong(val)
  289. int     val;
  290. {       if( gentype == longgen && outcol < 56) {
  291.                 fprintf(output,",%d",val);
  292.                 outcol += 10;
  293.                 }
  294.         else    {
  295.                 nl();
  296.                 fprintf(output,"\tlong\t%d",val);
  297.                 gentype = longgen;
  298.                 outcol = 25;
  299.                 }
  300. }
  301.  
  302. genref(sp,offset)
  303. SYM     *sp;
  304. int     offset;
  305. {       char    sign;
  306.         if( offset < 0) {
  307.                 sign = '-';
  308.                 offset = -offset;
  309.                 }
  310.         else
  311.                 sign = '+';
  312.         if( gentype == longgen && outcol < 55 - strlen(sp->name)) {
  313.                 if( sp->storage_class == sc_static)
  314.                         fprintf(output,",L%%%d%c%d",sp->value.i,sign,offset);
  315.                 else
  316.                         fprintf(output,",%s%c%d",sp->name,sign,offset);
  317.                 outcol += (11 + strlen(sp->name));
  318.                 }
  319.         else    {
  320.                 nl();
  321.                 if(sp->storage_class == sc_static)
  322.                     fprintf(output,"\tlong\tL%%%d%c%d",sp->value.i,sign,offset);
  323.                 else
  324.                     fprintf(output,"\tlong\t%s%c%d",sp->name,sign,offset);
  325.                 outcol = 26 + strlen(sp->name);
  326.                 gentype = longgen;
  327.                 }
  328. }
  329.  
  330. genstorage(nbytes)
  331. int     nbytes;
  332. {       nl();
  333.         fprintf(output,"\tspace\t%d\n",nbytes);
  334. }
  335.  
  336. gen_labref(n)
  337. int     n;
  338. {       if( gentype == longgen && outcol < 58) {
  339.                 fprintf(output,",L%%%d",n);
  340.                 outcol += 6;
  341.                 }
  342.         else    {
  343.                 nl();
  344.                 fprintf(output,"\tlong\tL%%%d",n);
  345.                 outcol = 22;
  346.                 gentype = longgen;
  347.                 }
  348. }
  349.  
  350. int     stringlit(s)
  351. /*
  352.  *      make s a string literal and return it's label number.
  353.  */
  354. char    *s;
  355. {       struct slit     *lp;
  356.         ++global_flag;          /* always allocate from global space. */
  357.         lp = xalloc(sizeof(struct slit));
  358.         lp->label = nextlabel++;
  359.         lp->str = litlate(s);
  360.         lp->next = strtab;
  361.         strtab = lp;
  362.         --global_flag;
  363.         return lp->label;
  364. }
  365.  
  366. dumplits()
  367. /*
  368.  *      dump the string literal pool.
  369.  */
  370. {       char            *cp;
  371.         while( strtab != 0) {
  372.                 cseg();
  373.                 nl();
  374.                 put_label(strtab->label);
  375.                 cp = strtab->str;
  376.                 while(*cp)
  377.                         genbyte(*cp++);
  378.                 genbyte(0);
  379.                 strtab = strtab->next;
  380.                 }
  381.         nl();
  382. }
  383.  
  384. nl()
  385. {       if(outcol > 0) {
  386.                 fprintf(output,"\n");
  387.                 outcol = 0;
  388.                 gentype = nogen;
  389.                 }
  390. }
  391.  
  392. cseg()
  393. {       if( curseg != codeseg) {
  394.                 nl();
  395.                 fprintf(output,"\ttext\n");
  396.                 curseg = codeseg;
  397.                 }
  398. }
  399.  
  400. dseg()
  401. {       if( curseg != dataseg) {
  402.                 nl();
  403.                 fprintf(output,"\tdata\t2\n");
  404.                 curseg = dataseg;
  405.                 }
  406. }
  407.